package com.kujie.access.trigger;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kujie.access.domain.po.AccessEnterpriseRentalInformation;
import com.kujie.access.domain.po.AccessTenantManagement;
import com.kujie.access.domain.vo.EnterpriseRentalInformationVO;
import com.kujie.access.enums.LeaseExpirationWarnEnum;
import com.kujie.access.mapper.AccessEnterpriseRentalInformationMapper;
import com.kujie.access.mapper.AccessTenantManagementMapper;
import com.kujie.common.core.utils.DateUtil;
import com.kujie.common.core.utils.ObjectUtils;
import com.kujie.common.redis.utils.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 租赁到期预警定时任务
 *
 * @author check
 * @date 2025-07-17
 */
@Component
@RequiredArgsConstructor
public class LeaseExpirationWarnTrigger {
    Logger logger = LoggerFactory.getLogger("LeaseExpirationWarnTrigger");

    private final AccessTenantManagementMapper accessTenantManagementMapper;
    private final AccessEnterpriseRentalInformationMapper enterpriseRentalInformationMapper;

    //    @Scheduled(cron = "0 0 0 * * ?")
    @Scheduled(cron = "0 * * * * ?")
    public void leaseExpirationWarn() {
        logger.info("定时扫描到期预警提示任务开始执行");

        // 执行前先删除对应的redis缓存
        deleteRedisKey();

        // 查询所有企业信息
        List<AccessTenantManagement> accessTenantManagements = accessTenantManagementMapper.selectList();
        Map<String, AccessTenantManagement> companyUuidToCompany = accessTenantManagements.stream().collect(Collectors.toMap(AccessTenantManagement::getCompanyUuid, Function.identity()));

        // 查询企业租赁信息
        List<AccessEnterpriseRentalInformation> accessEnterpriseRentalInformations = enterpriseRentalInformationMapper.selectList(
            new LambdaQueryWrapper<AccessEnterpriseRentalInformation>().in(CollectionUtil.isNotEmpty(companyUuidToCompany.keySet()), AccessEnterpriseRentalInformation::getCompanyUuid, companyUuidToCompany.keySet())
        );

        List<EnterpriseRentalInformationVO> rentalInformationsZeroToFiveDays = new ArrayList<>();
        List<EnterpriseRentalInformationVO> rentalInformationsFiveToTenDays = new ArrayList<>();
        List<EnterpriseRentalInformationVO> rentalInformationsTenToFifteenDays = new ArrayList<>();

        for (AccessEnterpriseRentalInformation accessEnterpriseRentalInformation : accessEnterpriseRentalInformations) {
            if (ObjectUtils.isEmpty(accessEnterpriseRentalInformation.getRentExpirationDate())) {
                continue;
            }
            int days = DateUtil.differentDaysByLocalDate(accessEnterpriseRentalInformation.getRentExpirationDate(), LocalDate.now());
            if (days < 0 || days > 15) {
                continue;
            }

            EnterpriseRentalInformationVO enterpriseRentalInformationVO = new EnterpriseRentalInformationVO(
                BeanUtil.copyProperties(accessEnterpriseRentalInformation, AccessEnterpriseRentalInformation.class),
                companyUuidToCompany.get(accessEnterpriseRentalInformation.getCompanyUuid())
            );

            if (days <= 5) {
                rentalInformationsZeroToFiveDays.add(enterpriseRentalInformationVO);
            } else if (days <= 10) {
                rentalInformationsFiveToTenDays.add(enterpriseRentalInformationVO);
            } else {
                rentalInformationsTenToFifteenDays.add(enterpriseRentalInformationVO);
            }
        }

        List<EnterpriseRentalInformationVO> allRentalInformations = new ArrayList<>();
        allRentalInformations.addAll(rentalInformationsZeroToFiveDays);
        allRentalInformations.addAll(rentalInformationsFiveToTenDays);
        allRentalInformations.addAll(rentalInformationsTenToFifteenDays);

        // 缓存数据
        saveRedisKey(rentalInformationsZeroToFiveDays, rentalInformationsFiveToTenDays, rentalInformationsTenToFifteenDays, allRentalInformations);
        logger.info("定时扫描到期预警提示任务执行完毕");
    }

    private static void saveRedisKey(List<EnterpriseRentalInformationVO> rentalInformationsZeroToFiveDays,
                                     List<EnterpriseRentalInformationVO> rentalInformationsFiveToTenDays,
                                     List<EnterpriseRentalInformationVO> rentalInformationsTenToFifteenDays,
                                     List<EnterpriseRentalInformationVO> allRentalInformations) {
        RedisUtils.setCacheObject(LeaseExpirationWarnEnum.ALL.getDescription(), allRentalInformations);
        RedisUtils.setCacheObject(LeaseExpirationWarnEnum.ZERO_TO_FIVE.getDescription(), rentalInformationsZeroToFiveDays);
        RedisUtils.setCacheObject(LeaseExpirationWarnEnum.FIVE_TO_TEN.getDescription(), rentalInformationsFiveToTenDays);
        RedisUtils.setCacheObject(LeaseExpirationWarnEnum.TEN_TO_FIFTEEN.getDescription(), rentalInformationsTenToFifteenDays);
    }

    private static void deleteRedisKey() {
        RedisUtils.deleteObject(LeaseExpirationWarnEnum.ALL.getDescription());
        RedisUtils.deleteObject(LeaseExpirationWarnEnum.ZERO_TO_FIVE.getDescription());
        RedisUtils.deleteObject(LeaseExpirationWarnEnum.FIVE_TO_TEN.getDescription());
        RedisUtils.deleteObject(LeaseExpirationWarnEnum.TEN_TO_FIFTEEN.getDescription());
    }
}
